package com.dmcb.common.business.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日期工具类
 * Created by long on 2015/3/21.
 */
@Component
public class DateUtil {

    public static String format(final Date object) {
        return format(object, "yyyy-MM-dd");
    }

    public static String formatMinutes(final Date object) {
        return format(object, "yyyy-MM-dd HH:mm");
    }

    public static String formatMinutes2(final Date object) {
        return format(object, "yyyy-MM-dd HH:mm:ss");
    }
    public static Object formatByStringAndT(final String object,boolean string) {
        SimpleDateFormat formatter = new SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss");
        Date date  = null;
        try {
            date = formatter.parse(object);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if(date != null & string){
            return formatMinutes2(date);
        }

        return date;
    }
    public static String formatShort(final Date object) {
        return format(object, "yyyyMMdd");
    }

    public static String formatShorter(final Date object) {
        return format(object, "yyMMdd");
    }

    public static String format(final Date object, String format) {
        if (object == null) {
            return null;
        }
        final SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(object);
    }

    public static String formatTime(final Date object) {
        return format(object, "yyyyMMddHHmmss");
    }

    /**
     * n小时前、n天前、n个月前转日期
     */
    public static Date transfer(String d) {
        if (StringUtils.isBlank(d)) {
            return null;
        }
        Integer n = RegexUtil.getNum(d);
        if (n == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        int field = -1;
        if (d.contains("分钟前")) {
            field = Calendar.MINUTE;
        } else if (d.contains("小时前")) {
            field = Calendar.HOUR_OF_DAY;
        } else if (d.contains("天前")) {
            field = Calendar.DATE;
        } else if (d.contains("月前")) {
            field = Calendar.MONTH;
        } else if (d.contains("年前")) {
            field = Calendar.YEAR;
        }
        if (field == -1) {
            return null;
        }
        c.add(field, -n);
        return c.getTime();
    }

    public static long secondDiff(Date begin) {
        if (begin == null) {
            return 0l;
        }
        return (Calendar.getInstance().getTimeInMillis() - begin.getTime()) / 1000;
    }

    public static int dayDiff(Date begin) {
        if (begin == null) {
            return 0;
        }
        return (int) (secondDiff(begin) / 86400);
    }

    public static Date toDate(String str, String dateFormat) {
        DateFormat format = new SimpleDateFormat(dateFormat);
        try {
            return format.parse(str);
        } catch (ParseException e) {
            return null;
        }
    }

    public static Date parseDate(String date) {
        if (StringUtils.isBlank(date)) {
            return null;
        }
        date = date.trim();
        date = date.replace(".", "-").replace("年", "-").replace("月", "-").replace("日 ", " ").replace("日", " ").replace("/", "-");
        date = matchDate(date);
        try {
            SimpleDateFormat sdf;
            if (date.indexOf("-") == date.lastIndexOf("-")) {
                date = format(new Date(), "yyyy-") + date;
            }
            if (date.contains(":")) {
                if (date.indexOf(":") == date.lastIndexOf(":")) {
                    sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                }
            } else {
                sdf = new SimpleDateFormat("yyyy-MM-dd");
            }
            return sdf.parse(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * (1)能匹配的年月日类型有：
     * 2014年4月19日
     * 2014年4月19号
     * 2014-4-19
     * 2014/4/19
     * 2014.4.19
     * (2)能匹配的时分秒类型有：
     * 15:28:21
     * 15:28
     * 5:28 pm
     * 15点28分21秒
     * 15点28分
     * 15点
     * (3)能匹配的年月日时分秒类型有：
     * (1)和(2)的任意组合，二者中间可有任意多个空格
     * 如果dateStr中有多个时间串存在，只会匹配第一个串，其他的串忽略
     *
     * @param str 字符
     * @return 日期
     */
    public static String matchDate(String str) {
        Pattern p = Pattern.compile("(\\d{1,4}[-|\\/|年|\\.]\\d{1,2}[-|\\/|月|\\.]\\d{1,2}([日|号])?(\\s)*(\\d{1,2}([点|时])?((:)?\\d{1,2}(分)?((:)?\\d{1,2}(秒)?)?)?)?(\\s)*(PM|AM)?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
        Matcher matcher = p.matcher(str);//使用正则表达式判断日期
        if (matcher.find()) {
            return matcher.group();//返回找到的日期
        }
        return str;
    }

    public static Date oneSecondBefore(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, -1);
        return c.getTime();
    }

    public static String getAs() {
        long time = System.currentTimeMillis() / 1000;
        String hexStr = Integer.toHexString((int) time);
        String md5 = getMD5(time + "");
        String code = "A1" + md5.charAt(0) + hexStr.charAt(0)
                + md5.charAt(1) + hexStr.charAt(1)
                + md5.charAt(2) + hexStr.charAt(2)
                + md5.charAt(3) + hexStr.charAt(3)
                + md5.charAt(4) + hexStr.charAt(4)
                + hexStr.charAt(5) + hexStr.charAt(6) + hexStr.charAt(7);
        return code.toUpperCase();

    }

    public static Long getUnixTime() {
        long time = System.currentTimeMillis() / 1000;
        return time;
    }

    /*
      * 将时间戳转换为时间
      */
    public static Date stampToDate(String beginDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sd = sdf.format(new Date(Long.parseLong(beginDate + "000")));
        return sdf.parse(sd);
    }

    public static String getMD5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            return "";
        }
    }


   /* public static void main(String[] args) {
        try {
            String timeStr = "2018-09-06T21:22:48.067+0800";

            SimpleDateFormat formatter = new SimpleDateFormat(
                    "yyyy-MM-dd'T'HH:mm:ss");
            try {
                Date date = formatter.parse(timeStr);
                System.out.println(date);
                System.out.println(date.getTime());
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }*/

    //获取指定日期的月份的天数
    public static int getDays(String time) {
        Calendar rightNow = Calendar.getInstance();
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy/MM"); //如果写成年月日的形式的话，要写小d，如："yyyy/MM/dd"
        try {
            rightNow.setTime(simpleDate.parse(time)); //要计算你想要的月份，改变这里即可
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int days = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH);
        return days;

    }


    /**
     * 获取指定月的前一月（年）或后一月（年）
     *
     * @param dateStr
     * @param addYear
     * @param addMonth
     * @param addDate
     * @return 输入的时期格式为yyyy-MM-dd，输出的日期格式为yyyy-MM-dd
     * @throws Exception
     */
    public static Date getLastDay(String dateStr, int addYear, int addMonth, int addDate) throws Exception {
        SimpleDateFormat sdf;
        SimpleDateFormat returnSdf;
        if (dateStr.contains(":") && dateStr.indexOf(":") != dateStr.lastIndexOf(":")) {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            returnSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } else if (dateStr.contains(":") && dateStr.indexOf(":") == dateStr.lastIndexOf(":")) {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            returnSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        } else if (!dateStr.contains(":") && dateStr.indexOf("-") != dateStr.lastIndexOf("-")) {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
            returnSdf = new SimpleDateFormat("yyyy-MM-dd");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM");
            returnSdf = new SimpleDateFormat("yyyy-MM");
        }
        try {
            Date sourceDate = sdf.parse(dateStr);
            Calendar cal = Calendar.getInstance();
            cal.setTime(sourceDate);
            cal.add(Calendar.YEAR, addYear);
            cal.add(Calendar.MONTH, addMonth);
            cal.add(Calendar.DATE, addDate);
            String dateTmp = returnSdf.format(cal.getTime());

            return parseDate(dateTmp);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }

    /**
     * @param time
     * @return
     */
    public static String getTimeByDianZiBao(String time) {
        Date date = new Date();
        time = StringUtils.isBlank(time) ? format(date) : time;
        String leftTime = time.substring(0, time.lastIndexOf("-"));
        String rightTime = time.substring(time.lastIndexOf("-") + 1, time.length());
        if (rightTime.length() < 2) {
            rightTime = "0" + rightTime;
        }
        time = leftTime + "/" + rightTime;
        return time;
    }

    /**
     *
     * @param size 数量，单位秒
     * @throws InterruptedException
     */
    public static void sleep(int size) {
        for (int i = 0; i < size; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
